/*
 *  modifier: Honrun
 *  date:     2023/10/29 20:42
 */
#include "stdio.h"
#include "string.h"
#include "microCPU.h"
#include "microList.h"
#include "microMemory.h"
#include "microTimer.h"
#include "microTask.h"


/* 当前正在运行的任务 */
volatile MrTaskType *g_ptypeMrTaskCurrent = NULL;

/* 空闲任务控制块 */
MrTaskType *g_ptypeMrTaskIdleHandle;

/* 定时器任务控制块 */
MrTaskType *g_ptypeMrTaskTimerHandle;

/* 就绪任务链表 */
MrListType g_typeMrListTaskReady = {&g_typeMrListTaskReady, &g_typeMrListTaskReady};


void vMrTaskIdle(uint32_t uiParameters)
{
    while(1)
    {
        /* 触发任务切换 */
        vMrCpuYield();

        /* 计算CPU使用率 */
        vMrCpuUsageGage();
    }
}

void vMrTaskError(void)
{
    while(1)
    {
    }
}

int8_t cMrTaskCreate(MrTaskType **pptypeTaskHandle, vMrTaskFunction pvTaskFunction, char *pcName, int32_t iPriority, int32_t iStackSize, uint32_t uiParameters)
{
    MrTaskType *ptypeTaskNow = NULL;
    uint8_t *pucStackTop = NULL;

    if(pvTaskFunction == NULL)
        return 1;

    /* 申请任务控制块 */
    if((ptypeTaskNow = pvMrMemoryCalloc(1, sizeof(MrTaskType))) == NULL)
        return 2;

    iStackSize = (iStackSize < configMr_TASK_STACK_SIZE_MIN) ? configMr_TASK_STACK_SIZE_MIN : iStackSize;

    /* N 字节对齐 */
    iStackSize = mrMemoryRoundUp(iStackSize, MR_MEMORY_ROUNDUP_VALUE);

    /* 申请任务栈 */
    if((pucStackTop = pvMrMemoryCalloc(iStackSize, sizeof(uint8_t))) == NULL)
    {
        vMrMemoryFree(ptypeTaskNow);
        return 3;
    }

    /* 栈底，调试时使用 */
    ptypeTaskNow->pStackEnd = (uint32_t *)pucStackTop;

    /* 移动到栈顶 */
    pucStackTop += iStackSize;

    /* 任务栈初始化 */
    ptypeTaskNow->pStackTop = puiMrTaskStackInit((uint32_t *)pucStackTop, pvTaskFunction, uiParameters);

    /* 任务名 */
    strncpy(ptypeTaskNow->name, pcName, sizeof(ptypeTaskNow->name) - 1);
    /* 任务优先级 */
    ptypeTaskNow->priority = iPriority;

    /* 初始化链表信息 */
    cMrListInit(&ptypeTaskNow->list, iPriority);
    cMrListInit(&ptypeTaskNow->listDelay, 0);
    ptypeTaskNow->list.pElement = ptypeTaskNow->listDelay.pElement = ptypeTaskNow;

    /* 进入临界段 */
    vMrCpuDisableIsr();

    /* 插入到就绪链表 */
    cMrListInsert(&g_typeMrListTaskReady, &ptypeTaskNow->list);

    /* 退出临界段 */
    vMrCpuEnableIsr();

    if(pptypeTaskHandle != NULL)
        *pptypeTaskHandle = ptypeTaskNow;

    return 0;
}

/* 恢复任务 */
int8_t cMrTaskResume(MrTaskType *ptypeTaskHandle)
{
    if(ptypeTaskHandle == NULL)
        return 1;

    /* 进入临界段 */
    vMrCpuDisableIsr();

    /* 从当前链表中移除 */
    cMrListRemove(&ptypeTaskHandle->list);
    cMrListRemove(&ptypeTaskHandle->listDelay);

    /* 插入到就绪链表 */
    ptypeTaskHandle->list.value = ptypeTaskHandle->priority;
    cMrListInsert(&g_typeMrListTaskReady, &ptypeTaskHandle->list);

    /* 退出临界段 */
    vMrCpuEnableIsr();

    /* 触发任务切换 */
    vMrCpuYield();

    return 0;
}

/* 挂起任务 */
int8_t cMrTaskSuspend(MrTaskType *ptypeTaskHandle)
{
    ptypeTaskHandle = (ptypeTaskHandle == NULL) ? (MrTaskType *)g_ptypeMrTaskCurrent : ptypeTaskHandle;

    /* 进入临界段 */
    vMrCpuDisableIsr();

    /* 从链表中移除 */
    cMrListRemove(&ptypeTaskHandle->list);
    cMrListRemove(&ptypeTaskHandle->listDelay);

    /* 退出临界段 */
    vMrCpuEnableIsr();

    /* 触发任务切换 */
    vMrCpuYield();

    return 0;
}

/* 查找当前就绪链表内最高优先级的任务 */
MrTaskType *ptypeMrTaskReadyPreviousHighGet( void )
{
    MrListType *ptypeListHigh = NULL, *ptypeListPrevious = NULL;
    MrTaskType *ptypeTaskNow = NULL;

    /* 进入临界段 */
    vMrCpuDisableIsr();

    /* 从小到大，排序存储，最后一个就是优先级最高的任务 */
    ptypeListHigh = g_typeMrListTaskReady.pPrevious;
    ptypeListPrevious = g_ptypeMrTaskCurrent->list.pPrevious;

    /* 就绪任务的最高优化级无变化，轮流执行 */
    if((ptypeListPrevious->value == ptypeListHigh->value) && (ptypeListPrevious != &g_typeMrListTaskReady) && (ptypeListPrevious->pNext != ptypeListPrevious))
    {
        ptypeTaskNow = (MrTaskType *)ptypeListPrevious->pElement;
    }
    /* 就绪任务的最高优化级有变化 */
    else
    {
        ptypeTaskNow = (MrTaskType *)ptypeListHigh->pElement;
    }

    /* 退出临界段 */
    vMrCpuEnableIsr();

    return ptypeTaskNow;
}

/* 更新到最高优先级 */
void vMrTaskSwitchContext( void )
{
    /* 进入临界段 */
    vMrCpuDisableIsr();

    g_ptypeMrTaskCurrent = ptypeMrTaskReadyPreviousHighGet();

    /* 退出临界段 */
    vMrCpuEnableIsr();
}

int8_t cMrTaskStart(void)
{
    /* 创建空闲任务 */
    cMrTaskCreate(&g_ptypeMrTaskIdleHandle,  vMrTaskIdle,  "IDLE", -999, configMr_TASK_STACK_SIZE_MIN,  0);

    /* 创建定时器任务 */
    cMrTaskCreate(&g_ptypeMrTaskTimerHandle, vMrTaskTimer, "Timer", configMr_PRIORITY_TIMER, configMr_TASK_STACK_SIZE_MIN, 0);

    /* 系统启动时，先指向空闲任务 */
    g_ptypeMrTaskCurrent = g_ptypeMrTaskIdleHandle;

    /* 系统时钟初始化 */
    cMrCpuTickTimerInit();

    /* 启动RTOS调度 */
    vMrCpuStartFirstTask();

    /* RTOS正常启动后，不会运行到这 */
    vMrTaskError();

    return 1;
}
